/*****************************************************************************
 * Copyright (c) 2019, Nations Technologies Inc.
 *
 * All rights reserved.
 * ****************************************************************************
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Nations' name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ****************************************************************************/

/**
 * @file n32wb03x_qflash.c
 * @author Nations Firmware Team
 * @version v1.0.2
 *
 * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
 */
#include "n32wb03x_qflash.h"
#include <string.h>
/** @addtogroup n32wb03x_StdPeriph_Driver
 * @{
 */

/** @addtogroup QFLASH
 * @brief QFLASH driver modules
 * @{
 */
 

/** @addtogroup QFLASH_Private_TypesDefinitions
 * @{
 */

/**
 * @}
 */

/** @addtogroup QFLASH_Private_Defines
 * @{
 */

#define GLOBAL_INT_DISABLE()        \
uint32_t ui32IntStatus = 0;         \
do{                                 \
    ui32IntStatus = __get_PRIMASK();\
    __set_PRIMASK(1);               \
}while(0)

#define GLOBAL_INT_RESTORE()     \
do{                              \
    __set_PRIMASK(ui32IntStatus);\
}while(0)

/**
 * @}
 */

/** @addtogroup QFLASH_Private_Macros
 * @{
 */

/**
 * @}
 */

/** @addtogroup QFLASH_Private_Variables
 * @{
 */

static __align(4) unsigned char _acCMD_BIN[0x324] = {
0x01,0x38,0xfd,0xd1,0x70,0x47,0x00,0x00,0xf0,0xb4,0x03,0x24,0xa4,0x06,0x23,0x6a,
0x5b,0x08,0x5b,0x00,0x23,0x62,0x23,0x6a,0x02,0x25,0x2b,0x43,0x23,0x62,0x23,0x6a,
0x9b,0x07,0xfc,0xd4,0xff,0x23,0x01,0x33,0xa3,0x62,0x65,0x69,0xde,0x1d,0xb5,0x43,
0x65,0x61,0x65,0x69,0x1e,0x1d,0x35,0x43,0x65,0x61,0x00,0x02,0x6b,0x30,0x60,0x60,
0x08,0x20,0xa0,0x60,0xe2,0x60,0x01,0x26,0x26,0x61,0xa0,0x6a,0xc0,0x05,0xfc,0xd5,
0xa3,0x62,0x00,0x23,0xd2,0x1c,0x90,0x08,0x0e,0xd0,0x95,0x08,0x0f,0x48,0x00,0x68,
0x9a,0x00,0x88,0x54,0x07,0x0a,0x52,0x18,0x57,0x70,0x07,0x0c,0x00,0x0e,0x97,0x70,
0x5b,0x1c,0xd0,0x70,0x9d,0x42,0xf1,0xd8,0x60,0x69,0xff,0x21,0x08,0x31,0x88,0x43,
0x60,0x61,0x60,0x69,0x30,0x43,0x60,0x61,0x20,0x6a,0x80,0x08,0x80,0x00,0x20,0x62,
0x20,0x6a,0x30,0x43,0x20,0x62,0xf0,0xbc,0x00,0x20,0x70,0x47,0x80,0x00,0x00,0x0c,
0xf8,0xb5,0x06,0x46,0x01,0x20,0x00,0x25,0xc0,0x04,0x86,0x42,0x01,0xd9,0x05,0x20,
0xf8,0xbd,0x03,0x24,0xa4,0x06,0x20,0x6a,0x40,0x08,0x40,0x00,0x20,0x62,0x20,0x6a,
0x02,0x21,0x08,0x43,0x20,0x62,0x20,0x6a,0x80,0x07,0xfc,0xd4,0xff,0x27,0x01,0x37,
0xa7,0x62,0x00,0xf0,0xbb,0xf8,0x00,0x28,0x01,0xd0,0x03,0x25,0x15,0xe0,0x06,0x20,
0x60,0x60,0x01,0x21,0x21,0x61,0xa0,0x6a,0xc0,0x05,0xfc,0xd5,0xa7,0x62,0x30,0x02,
0x20,0x30,0x60,0x60,0x21,0x61,0xa0,0x6a,0xc0,0x05,0xfc,0xd5,0xa7,0x62,0x0c,0x48,
0x00,0xf0,0xc8,0xf8,0x00,0x28,0x00,0xd1,0x02,0x25,0x60,0x69,0xff,0x21,0x08,0x31,
0x88,0x43,0x60,0x61,0x60,0x69,0x01,0x21,0x08,0x43,0x60,0x61,0x20,0x6a,0x80,0x08,
0x80,0x00,0x20,0x62,0x20,0x6a,0x08,0x43,0x20,0x62,0x28,0x46,0xf8,0xbd,0x00,0x00,
0xe6,0x96,0x01,0x00,0xf7,0xb5,0x06,0x46,0x01,0x20,0xc0,0x04,0x82,0xb0,0x15,0x46,
0x86,0x42,0x02,0xd9,0x05,0x20,0x05,0xb0,0xf0,0xbd,0x03,0x20,0x80,0x06,0x01,0x6a,
0x49,0x08,0x49,0x00,0x01,0x62,0x01,0x6a,0x02,0x22,0x11,0x43,0x01,0x62,0x01,0x6a,
0x89,0x07,0xfc,0xd4,0xff,0x21,0x01,0x31,0x81,0x62,0xf2,0xb2,0x8c,0x1a,0xa5,0x42,
0x00,0xd8,0xac,0xb2,0x03,0x98,0x00,0x90,0x00,0xf0,0x68,0xf8,0x00,0x28,0x40,0xd1,
0x06,0x21,0x48,0x06,0x41,0x60,0x01,0x21,0x01,0x61,0x81,0x6a,0xc9,0x05,0xfc,0xd5,
0xff,0x21,0x01,0x31,0x03,0x20,0x80,0x06,0x81,0x62,0x41,0x69,0xff,0x22,0x08,0x32,
0x91,0x43,0x41,0x61,0x41,0x69,0x04,0x22,0x11,0x43,0x41,0x61,0x31,0x02,0x32,0x31,
0x41,0x60,0xc4,0x60,0x00,0x22,0x00,0x2c,0x16,0xd9,0x00,0x98,0x87,0x18,0x3b,0x78,
0xf8,0x78,0x19,0x46,0x7b,0x78,0x00,0x06,0x1b,0x02,0x19,0x43,0xbb,0x78,0x1b,0x04,
0x19,0x43,0x01,0x43,0x08,0x02,0xf9,0x78,0x00,0x0a,0x09,0x06,0x08,0x43,0x19,0x49,
0x08,0x60,0x12,0x1d,0xa2,0x42,0xe8,0xd3,0x01,0x21,0x03,0x20,0x80,0x06,0x01,0x61,
0x81,0x6a,0xc9,0x05,0xfc,0xd5,0xff,0x21,0x01,0x31,0x81,0x62,0x12,0x48,0x00,0xf0,
0x49,0xf8,0xa5,0x42,0x09,0xd0,0x03,0x98,0x36,0x19,0x00,0x19,0x2d,0x1b,0xff,0x24,
0x01,0x34,0x03,0x90,0xa5,0x42,0xad,0xd8,0xab,0xe7,0x03,0x20,0x80,0x06,0x41,0x69,
0xff,0x22,0x08,0x32,0x91,0x43,0x41,0x61,0x41,0x69,0x01,0x22,0x11,0x43,0x41,0x61,
0x01,0x6a,0x89,0x08,0x89,0x00,0x01,0x62,0x01,0x6a,0x11,0x43,0x01,0x62,0x00,0x20,
0x05,0xb0,0xf0,0xbd,0x80,0x00,0x00,0x0c,0x1a,0x06,0x00,0x00,0x38,0xb4,0x01,0x25,
0x03,0x20,0x80,0x06,0x6a,0x46,0xc5,0x60,0x35,0x21,0x41,0x60,0x05,0x61,0x81,0x6a,
0xc9,0x05,0xfc,0xd5,0xff,0x24,0x01,0x34,0x84,0x62,0x81,0x69,0xc5,0x60,0xcb,0xb2,
0x05,0x21,0x41,0x60,0x05,0x61,0x81,0x6a,0xc9,0x05,0xfc,0xd5,0x84,0x62,0x80,0x69,
0x19,0x02,0xc0,0xb2,0x01,0x43,0x88,0xb2,0x11,0x80,0xc0,0x07,0x00,0xd0,0x01,0x20,
0x38,0xbc,0x70,0x47,0xf8,0xb4,0x00,0x21,0x01,0x25,0x03,0x22,0x92,0x06,0x6b,0x46,
0xd5,0x60,0x35,0x24,0x54,0x60,0x15,0x61,0x94,0x6a,0xe4,0x05,0xfc,0xd5,0xff,0x27,
0x01,0x37,0x97,0x62,0x94,0x69,0xd5,0x60,0xe4,0xb2,0x05,0x26,0x56,0x60,0x15,0x61,
0x96,0x6a,0xf6,0x05,0xfc,0xd5,0x97,0x62,0x96,0x69,0x24,0x02,0xf6,0xb2,0x34,0x43,
0x1c,0x80,0xe3,0x07,0x22,0xd0,0x81,0x42,0x02,0xd9,0xf8,0xbc,0x00,0x20,0x70,0x47,
0x03,0x22,0x92,0x06,0x6b,0x46,0xd5,0x60,0x35,0x24,0x54,0x60,0x15,0x61,0x49,0x1c,
0x94,0x6a,0xe4,0x05,0xfc,0xd5,0x97,0x62,0x94,0x69,0xd5,0x60,0xe4,0xb2,0x05,0x26,
0x56,0x60,0x15,0x61,0x96,0x6a,0xf6,0x05,0xfc,0xd5,0x97,0x62,0x92,0x69,0x24,0x02,
0xd2,0xb2,0x14,0x43,0xa2,0xb2,0x1c,0x80,0xd2,0x07,0xdc,0xd1,0xf8,0xbc,0x01,0x20,
0x70,0x47,0x00,0x00};

/**
 * @}
 */

/** @addtogroup QFLASH_Private_FunctionPrototypes
 * @{
 */
typedef ReturnMsg CMD_FLASH_SE_t( uint32_t flash_address) ;
typedef ReturnMsg CMD_FLASH_WRITE_t(uint32_t flash_address, uint8_t* p_data, uint32_t len);
typedef ReturnMsg CMD_FLASH_READ_t(uint32_t flash_address, uint8_t* p_data, uint32_t len);

ReturnMsg (*CMD_FLASH_SE)( uint32_t flash_address);
ReturnMsg (*CMD_FLASH_WRITE)(uint32_t addr, uint8_t* p_data, uint32_t len);
ReturnMsg (*CMD_FLASH_READ)(uint32_t addr, uint8_t* p_data, uint32_t len);

/**
 * @}
 */

/** @addtogroup QFLASH_Private_Functions
 * @{
 */

/**
 * @brief  Initialize Qflash.
 */
void Qflash_Init(void)
{
    //Init Qflash algorithm  
    CMD_FLASH_SE = (CMD_FLASH_SE_t *)(_acCMD_BIN + 0xA1);   
    CMD_FLASH_WRITE = (CMD_FLASH_WRITE_t *)(_acCMD_BIN + 0x135);  
    CMD_FLASH_READ = (CMD_FLASH_READ_t *)(_acCMD_BIN + 0x09);  
}

/**
 * @brief Erase one sector in flash with ble schedule on.
 * @param[in] flash_address erase address.
 * @return none.
 */
uint32_t Qflash_Erase_Sector(uint32_t address)
{
    ReturnMsg error;
    GLOBAL_INT_DISABLE();
    address -= 0x01000000;
    assert_param(CMD_FLASH_SE != NULL);
    error = CMD_FLASH_SE(address);
    assert_param(error == FlashOperationSuccess);
    GLOBAL_INT_RESTORE();
    return error;
}

/**
 * @brief Write mutable length data to flash with ble schedule on.
 * @param[in] addr flash address.
 * @param[in] p_data data to write.
 * @param[in] len data len.
 * @return none.
 */
uint32_t Qflash_Write(uint32_t address, uint8_t* p_data, uint32_t len)
{
    ReturnMsg error;
    GLOBAL_INT_DISABLE();
    address -= 0x01000000;
    assert_param(CMD_FLASH_WRITE != NULL);
    error = CMD_FLASH_WRITE(address, p_data, len);
    assert_param(error == FlashOperationSuccess);
    GLOBAL_INT_RESTORE();
    return error;
}


/**
 * @brief Read mutable length data to ram.
 * @param[in] addr flash address.
 * @param[out] p_data data to read.
 * @param[in] len data len.
 * @return none.
 */
uint32_t Qflash_Read(uint32_t address, uint8_t* p_data, uint32_t len)
{
    
    ReturnMsg error;
    GLOBAL_INT_DISABLE();    
    address -= 0x01000000;
    assert_param(CMD_FLASH_READ != NULL);
    error = CMD_FLASH_READ(address, p_data, len);
    assert_param(error == FlashOperationSuccess);
    GLOBAL_INT_RESTORE();
    return error;
}


/**
 * @}
 */ 

/**
 * @}
 */ 

/**
 * @}
 */ 



